﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;


namespace VCC.Model
{
    public class CategoryManager
    {
        public static List<Category> GetChildCategory(int catid)
        {
            try
            {
                var db = new ChoVietDataContext();
                var returnVal = new List<Category>();
                var curentCat = db.Categories.Single(o => o.ID == catid);
                returnVal.Add(curentCat);

                foreach (var item in curentCat.Categories)
                {
                    returnVal.AddRange(GetChildCategory(item.ID));
                }

                return returnVal;
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static List<Category> GetListCategory()
        {
            var db = new ChoVietDataContext();
            try
            {
                var returnVal = new List<Category>();
                var listParent = db.Categories.Where(e => e.ParentID == null).OrderBy(e => e.Name).ToList();
                foreach (var item in listParent)
                {
                    var l = GetChildCategory(item.ID);
                    returnVal.AddRange(l);
                }
                return returnVal;
            }
            finally {db.Dispose();}
        }

        public static List<int> GetChild(int catid)
        {
            try
            {
                var db = new ChoVietDataContext();
                var returnVal = new List<int>();
                var curentCat = db.Categories.Single(o => o.ID == catid);
                returnVal.Add(curentCat.ID);

                foreach (var item in curentCat.Categories)
                {
                    returnVal.AddRange(GetChild(item.ID));
                }

                return returnVal;
            }
            catch (Exception)
            {
                return null;
            }
        }
        
        public static IList<Category> GetRoot(IList<Category> list)
        {
            IList<Category> root = new List<Category>();
            foreach (Category objCheck in list)
            {
                if (objCheck.ParentID == null || objCheck.ParentID <= 0 || objCheck.ID == objCheck.ParentID)
                {
                    root.Add(objCheck);
                }
            }
            return root;
        }

        public static Category GetOne(int id)
        {
            ChoVietDataContext db = new ChoVietDataContext();
            var l = db.Categories.Where(c => c.ID == id).ToList();
            return l != null && l.Count > 0 ? l.First() : null;
        }

        public static IList<TreeNodeCat> BuildTree(IList<Category> list)
        {
            IList<Category> roots = GetRoot(list);
            IList<TreeNodeCat> ret = new List<TreeNodeCat>();
            foreach (Category _obj in roots)
            {
                TreeNodeCat _node = new TreeNodeCat(_obj);
                _node.BuildChilNodes(list);
                ret.Add(_node);
            }
            return ret;
        }

        public static void ListTree(IList<TreeNodeCat> listNodes, IList<Category> listResult)
        {
            foreach (TreeNodeCat _node in listNodes)
            {
                listResult.Add(_node.Nodevalue);
                ListTree(_node.ChildNodes, listResult);
            }
        }

        public static void ListNode(TreeNodeCat node, IList<Category> listResult)
        {
            foreach (TreeNodeCat _node in node.ChildNodes)
            {
                listResult.Add(_node.Nodevalue);
                ListNode(_node, listResult);
            }
        }

        public static IList<Category> ListTree(IList<Category> list)
        {
            IList<TreeNodeCat> tree = BuildTree(list);
            IList<Category> l = new List<Category>();
            ListTree(tree, l);
            return l;
        }

        public static IList<SelectListItem> BuiltCombobox(int currentId)
        {

            IList<Category> list = GetAll(0);
            IList<Category> l = ListTree(list);
            string space = string.Empty;
            if (l != null)
            {
                IList<SelectListItem> sList = new List<SelectListItem>();
                foreach (var c in l)
                {
                    SelectListItem item = new SelectListItem();
                    if (c.ParentCategory == null)
                    {
                        space += " ";
                    }
                    else if (c.ParentCategory != null)
                    {
                        space += "- - -";
                    }

                    item.Text = space + c.Name;
                    item.Value = c.ID.ToString();
                    item.Selected = c.ID == currentId ? true : false;
                    sList.Add(item);
                    space = string.Empty;
                }
                return sList;
            }

            return new List<SelectListItem>();
        }

        public static IList<SelectListItem> BuiltComboboxShortName(int currentId)
        {

            IList<Category> list = GetAll(0);
            IList<Category> l = ListTree(list);
            string space = string.Empty;
            if (l != null)
            {
                IList<SelectListItem> sList = new List<SelectListItem>();
                foreach (var c in l)
                {
                    SelectListItem item = new SelectListItem();
                    if (c.ParentCategory == null)
                    {
                        space += " ";
                    }
                    else if (c.ParentCategory != null)
                    {
                        space += "- - -";
                    }

                    item.Text = space + c.Name;
                    item.Value = c.ShortName;
                    item.Selected = c.ID == currentId ? true : false;
                    sList.Add(item);
                    space = string.Empty;
                }
                return sList;
            }

            return new List<SelectListItem>();
        }
        
        public static IList<Category> GetAll(int parentid)
        {
            try
            {
                ChoVietDataContext db = new ChoVietDataContext();
                IList<Category> l = new List<Category>();
                var list = (from o in db.Categories where (parentid > 0 ? (parentid == null ? o.ParentID == null : o.ParentID.Value == parentid) : (1 == 1)) select o).ToList();

                return list;
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public static int[] GetArrayChildId(int parentid)
        {
            try
            {
                int pid = parentid;
                if (parentid <= 0)
                {
                    ChoVietDataContext db = new ChoVietDataContext();
                    var root = db.Categories.Single(p => p.ParentID == null);
                    pid = root.ID;
                }
                string strCode = string.Empty;
                IList<Category> l = new List<Category>();
                IList<Category> lc = new List<Category>();
                l = GetAll(0);
                var tree = BuildTree(l);
                var node = TreeNodeCat.FindListNode(tree, pid);
                if (node != null)
                {
                    ListTree(node.ChildNodes, lc);
                    var a = (from t in lc select t.ID).ToArray();
                    return a;
                }
                return null;
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public static int[] GetArrayChildId(int parentid, bool addParentId)
        {
            try
            {
                if (!addParentId) return GetArrayChildId(parentid);
                else
                {
                    var l = GetArrayChildId(parentid);
                    if (l == null)
                    {
                        l = new int[1];
                        l[0] = parentid;
                        return l;
                    }
                    else
                    {
                        var list = l.ToList();
                        list.Add(parentid);
                        return list.ToArray();
                    }
                }
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public class TreeNodeCat
        {
            private Category _Nodevalue = null;
            public TreeNodeCat(Category mNodeValue)
            {
                _Nodevalue = mNodeValue;
            }
            public Category Nodevalue
            {
                get { return _Nodevalue; }
                set { _Nodevalue = value; }
            }

            private List<TreeNodeCat> _childNodes = new List<TreeNodeCat>();
            public List<TreeNodeCat> ChildNodes
            {
                get { return _childNodes; }
                set { _childNodes = value; }
            }
            public int NodeId
            {
                get { return (Nodevalue == null) ? 0 : Nodevalue.ID; }
            }
            public string NodeName
            {
                get { return (Nodevalue == null) ? "" : Nodevalue.Name; }
            }

            public void BuildChilNodes(IList<Category> ListNodes)
            {
                foreach (Category childObj in ListNodes)
                {
                    if (childObj.ParentID == Nodevalue.ID && childObj.ParentID != childObj.ID)
                    {
                        TreeNodeCat _node = new TreeNodeCat(childObj);
                        _node.BuildChilNodes(ListNodes);
                        this.ChildNodes.Add(_node);
                    }
                }
            }

            private bool isTerminalNode
            {
                get { return ChildNodes.Count <= 0; }
            }
            public static Category Find(TreeNodeCat _node, int catId)
            {
                if (_node.Nodevalue.ID == catId) return _node.Nodevalue;
                else
                    foreach (TreeNodeCat _childNode in _node.ChildNodes)
                    {
                        Category _obj = Find(_childNode, catId);
                        if (_obj != null) return _obj;
                    }

                return null;
            }
            public static TreeNodeCat FindNode(TreeNodeCat _node, int Id)
            {
                if (_node.Nodevalue.ID == Id) return _node;
                else
                    foreach (TreeNodeCat _childNode in _node.ChildNodes)
                    {
                        TreeNodeCat _obj = FindNode(_childNode, Id);
                        if (_obj != null) return _obj;
                    }

                return null;
            }
            public static TreeNodeCat FindListNode(IList<TreeNodeCat> _nodes, int Id)
            {
                foreach (var obj in _nodes)
                {
                    var item = FindNode(obj, Id);
                    if (item != null) return item;
                }
                return null;
            }
        }
    }
}
